package cn.com.nes.common.util;

import cn.hutool.cache.impl.TimedCache;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import com.mashape.unirest.request.GetRequest;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.net.URLEncoder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TianyanchaCrawler {

    //缓存cookie, 两小时失效
    private static final TimedCache<String, Object> cache = new TimedCache<String, Object>(2 * 60 * 60 * 1000);

    public static int getRecordCount(String keyword) {
        final Object recordCount = cache.get(keyword + "&recordCount");
        return recordCount == null ? 0 : (Integer) recordCount;
    }

    public static int getPageCount(String keyword) {
        final Object pageCount = cache.get(keyword + "&pageCount");
        return pageCount == null ? 0 : (Integer) pageCount;
    }

    private String unsbox(String arg1) {
        Integer[] _0x4b082b = new Integer[]{0xf, 0x23, 0x1d, 0x18, 0x21, 0x10, 0x1, 0x26, 0xa, 0x9, 0x13, 0x1f, 0x28,
                0x1b, 0x16, 0x17, 0x19, 0xd, 0x6, 0xb, 0x27, 0x12, 0x14, 0x8, 0xe, 0x15,
                0x20, 0x1a, 0x2, 0x1e, 0x7, 0x4, 0x11, 0x5, 0x3, 0x1c, 0x22, 0x25, 0xc, 0x24};
        char[] _0x4da0dc = new char[arg1.length()];
        String _0x12605e;
        for (int _0x20a7bf = 0x0; _0x20a7bf < arg1.length(); _0x20a7bf++) {
            char _0x385ee3 = arg1.charAt(_0x20a7bf);
            for (int _0x217721 = 0x0; _0x217721 < _0x4b082b.length; _0x217721++) {
                if (_0x4b082b[_0x217721] == _0x20a7bf + 0x1) {
                    _0x4da0dc[_0x217721] = _0x385ee3;
                }
            }
        }
        _0x12605e = new String(_0x4da0dc);
        return _0x12605e;
    }

    private String hexXor(String s) {
        String _0x4e08d8 = "3000176000856006061501533003690027800375";
        StringBuilder _0x5a5d3b = new StringBuilder();
        for (int _0xe89588 = 0x0; _0xe89588 < s.length() && _0xe89588 < _0x4e08d8.length(); _0xe89588 += 0x2) {
            int _0x401af1 = Integer.valueOf(s.substring(_0xe89588, _0xe89588 + 0x2), 0x10);

            int _0x105f59 = Integer.valueOf(_0x4e08d8.substring(_0xe89588, _0xe89588 + 0x2), 0x10);

            String _0x189e2c = (Integer.toHexString(_0x401af1 ^ _0x105f59)).toUpperCase();

            if (_0x189e2c.length() == 0x1) {
                _0x189e2c = "0" + _0x189e2c;
            }
            _0x5a5d3b.append(_0x189e2c);
        }
        return _0x5a5d3b.toString();
    }

    public static String getCookie() throws UnirestException {
        String cookie = (String) cache.get("cookie", false);
        if (StrUtil.isEmpty(cookie)) {
            String url = "https://www.tianyancha.com/";
            Unirest.setTimeouts(0, 0);
            HttpResponse<String> response = Unirest.get(url).asString();
            String html = response.getBody();

            Pattern pattern = Pattern.compile("arg1='[0-9A-Z]+'");
            final Matcher matcher = pattern.matcher(html);
            //获取arg1, 并解密生成cookie
            if (matcher.find()) {
                String arg1 = matcher.group(0).replaceAll("arg1='", "").replaceAll("'", "");
                TianyanchaCrawler tianyanchaCrawler = new TianyanchaCrawler();
                cookie = tianyanchaCrawler.hexXor(tianyanchaCrawler.unsbox(arg1));
                System.out.println("cookie:" + cookie);
                cache.put("cookie", "acw_sc__v2=" + cookie);
            }
        }
        return cookie;
    }

    public static JSONArray searchCompanies(String keyword, int pageId) {
        String key = "keyword=" + keyword + "&pageId=" + pageId;
        JSONArray companies = (JSONArray) cache.get(key);
        if (companies != null) return companies;

        companies = new JSONArray();
        String html = "";
        try {
            StringBuilder url = new StringBuilder("https://www.tianyancha.com/search");
            String cookie = getCookie();
            if (pageId > 0 && pageId < 6) {
                url.append("/p").append(pageId);
            }
            String keywordParsed = URLEncoder.encode(keyword, "UTF-8");
            url.append("?key=").append(keywordParsed);

            System.out.println(url);
            Unirest.setTimeouts(0, 0);
            GetRequest request = Unirest.get(url.toString());
            if (StrUtil.isNotBlank(cookie)) {
                request = request.header("Cookie", cookie);
            }
            HttpResponse<String> response = request
                    .asString();
            html = response.getBody();
        } catch (Exception e) {
            e.printStackTrace();
        }

        Document doc = Jsoup.parse(html);

        //分页信息
        if (!cache.containsKey(keyword + "&pageCount")) {
            final int recordCount;
            try {
                final Element numTitle = doc.getElementsByTag("body").first()
                        .getElementById("__next")
                        .getElementById("page-container")
                        .getElementsByClass("index_search-module__xYupE").first()
                        .getElementsByClass("index_search-main__4nIOp").first()
                        .getElementsByClass("index_search-layout__0mlo8").first()
                        .getElementsByClass("index_layout-content___CNpU").first()
                        .getElementsByClass("index_search-list-wrap__wi3T0").first()
                        .getElementsByClass("index_toolbar-wrap__EB9Ed").first()
                        .getElementsByClass("index_toolbar-content__lr2Nk").first()
                        .getElementsByClass("index_content-tool__c6FkI").first()
                        .getElementsByClass("index_content-tool-title__K1Z6C").first()
                        .child(0)
                        .getElementsByClass("index_title-count__lDSjB").first()
                        ;
                recordCount = Integer.parseInt(numTitle.text());
                cache.put(keyword + "&recordCount", Math.min(recordCount, 100));
                System.out.println(recordCount);
            } catch (Exception e) {
                return companies;
            }

            int pageCount = 1;
            System.out.println(doc);
            if (recordCount > 1) {

                String maxPageNumber = recordCount % 20 == 0
                        ? String.valueOf(recordCount / 20)
                        : String.valueOf((recordCount / 20) + 1);
                maxPageNumber = maxPageNumber.replaceAll("\\.", "");
                pageCount = Math.min(Integer.parseInt(maxPageNumber), 5);
                System.out.println(pageCount);
            }
            cache.put(keyword + "&pageCount", pageCount);

        }

        //公司信息
//        Elements elements = doc.getElementsByClass("search-item sv-search-company  ");
        Elements elements = doc.getElementsByClass("index_search-box__7YVh6");
        for (Element e :
                elements) {
            try {
                Element singleResult = e.getElementsByClass("index_search-single__yOhYZ").get(0);
                Element content = singleResult.getElementsByClass("index_search-item__W7iG_").first()
                        .getElementsByClass("index_search-item-center__Q2ai5").first();

                //公司名称
//                String companyName = content.getElementsByClass("header").get(0).getElementsByClass("name select-none ").text();
                String companyName = content.getElementsByClass("index_header__x2QZ3").first()
                        .getElementsByClass("index_name__qEdWi").first()
                        .getElementsByClass("index_alink__zcia5 link-click").first()
                        .text();

                //法人
//                Element legalPersonElement = content.getElementsByClass("info row text-ellipsis").get(0)
//                        .getElementsByClass("title -wider text-ellipsis").get(0);
                Element legalPersonElement = content
                        .getElementsByClass("index_info-row__xbtyD index_line-row__R3mCi").first()
                        .getElementsByClass("index_info-col__UVcZb index_wider__gQok0").first();
                String legalPerson = legalPersonElement.hasClass("link-click")
                        ? legalPersonElement.getElementsByClass("link-click").get(0).text()
                        : legalPersonElement.child(0).text();

                //地址
//                String address = content.getElementsByClass("contact row").get(0)
//                        .getElementsByClass("col").get(0)
//                        .children().get(1).text();
                String address = content
                        .getElementsByClass("index_contact-row__iYUn6 index_line-row__R3mCi").first()
                        .getElementsByClass("index_contact-col__7AboU").first()
                        .children().get(1).text();

                Element logoElement = singleResult.getElementsByClass("index_search-item__W7iG_").first()
                        .getElementsByClass("index_search-item-left__eTjDK").first()
                        .getElementsByClass("index_hover-image-claim__6PJ3T").first();
                String logoText = logoElement.child(0).child(0).text();
                String logoImg = logoElement.child(0).child(0).attr("src");

                JSONObject company = new JSONObject();
                company.put("companyName", companyName);
                company.put("legalPerson", legalPerson);
                company.put("address", address);
                company.put("logoText", logoText);
                company.put("logoImg", logoImg);
                companies.add(company);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        cache.put(key, companies);
        return companies;
    }

    public static void main(String[] args) {
        System.out.println(TianyanchaCrawler.searchCompanies("热泵 山东", 2));
    }
}
